#include <iostream>
#include <vector>
#include <string>
#include <curl/curl.h>
#include <regex>
#include <sstream>
#include <filesystem>
#include <windows.h>

using namespace std;
const static string URL = "https://ssr1.scrape.center";
const static int PAGE = 10;
vector<string> URL_VT = vector<string>();
const static string PATH = "./movies";

size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* output){
    size_t totalSize = size * nmemb;
    output->append((char*)contents, titalSize);
    return totalSize;
}

string request_get(const string& url, map<string, string> headers = map<string, string>){
    CURL* curl;
    CURLcode statusCode;
    string htmlData;
    curl = curl_easy_init();
    if(curl){
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0);
        if(headers.find("cookies") != headers.end()){
            curl_easy_setopt(curl, CURLOPT_COOKIE, headers["cookies"].c_str());
        }
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &htmlData);
        auto res = curl_easy_perform(curl);
        if(res != CURLE_OK){
            std::cerr << "curl_easy_perform() failed:" << curl_easy_strerror(res) << std::endl;
        }
        curl_easy_cleanup(curl);
        return htmlData;
    }
    else{
        std::cerr << "curl_easy_init() failed." << std::endl;
        return "";
    }
    curl_global_cleanup();
}

bool contains(vector<string>& vt, const string& value){
    return find(vt.begin(), vt.end(), value) != vt.end();
}

void getURL(){
    string url;
    string html;
    regex reg("/detail/\\d+");
    smatch result;
    for(int page = 1; page <= PAGE; ++page){
        url = URL + "/page/" + to_string(page);
        string html = request_get(url);
        auto end_it = sregex_iterator();
        sregex_iterator it(html.begin(), html.end(), reg);
        for(; it != end_it; ++it){
            result = *it;
            if(!contains(URL_VT, result.str())){
                URL_VT.push_back(result.str());
            }
        }
    }
}

vector<string> findAll(const string& html, regex reg, int group = 0){
    auto end_it = sregex_iterator();
    vector<string> vt;
    smatch result;
    sregex_iterator it(html.begin(), html.end(), reg);
    for(; it != end_it; ++it){
        result = *it;
        vt.push_back(result[group].str());
    }
    return vt;
}

string vecToString(vector<string>& vt){
    ostringstream ostr;
    for(auto& w : vt){
        ostr << w << " ";
    }
    return ostr.str();
}

map<string,string> parseDetailPage(const strig& url){
    string html = request_get(url);
    smatch ResultTitle, ResultCategories, Res::ltArea, ResultTime, ResultPublish, ResultDrama, ResultScore;
    map<string, string> ResultMap;

    regex RegTitle(">(.*)</h2>");
    regex_search(html, ResultTitle, RegTitle);

    regex RegCategories("<span>(.*)</span>");
    vector<string> vt = findAll(html, RegCategories, 1);
    vt.pop_back();

    regex RegArea("\">([^x00-xff^/]+)</span>");
    regex_search(html, ResultArea, RegArea);

    regex RegTime(">(\\d+).*</span>");
    regex_search(html, ResultTime, RegTime);

    regex RegPublish("\\d+-\\d+-\\d+");
    regex_search(html, ResultPublish, RegPublish);

    regex RegDrama(">\\s+(.*)\\s+</p>");
    regex_search(html, ResultDrama, RegDrama);

    regex RegScore("\\d+\\.\\d+");
    regex_search(html, ResultScore, RegScore);

    ResultMap["title"] = ResultTitle[1].str();
    ResultMap["categories"] = ResultTitle[1].str();
    ResultMap["title"] = ResultTitle[1].str();
    ResultMap["title"] = ResultTitle[1].str();
    ResultMap["title"] = ResultTitle[1].str();
    ResultMap["title"] = ResultTitle[1].str();
    return ResultMap;
}

int main(){
    SetConsoleOutputCP(65001);
    if(!filesystem::exists(PATH)){
        filesystem::creat_directory(PATH);
    }
    getURL();
    string url;
    map<string,string> resultMap;
    string fileName;
    while(!URL_VT.empty()){
        url = URL_VT.back();
        URL_VT.pop_back();
        resultMap = parseDetailPage(url);
        fileName = PATH + "/" + resultMap["title"] + ".txt";
        fstream fout(fileName);
        for(auto& m : resultMap){
            fout<<m.first<<" "<<m.srcond<<endl;
        }
    }
}